<template>
	<view
		class="page-session"
		:style="{
			height,
		}"
		@touchmove="onTouchMove"
	>
		<view class="header">
			<cl-topbar>
				<view class="cl-topbar__text" @click="toDetail()">
					<text class="cl-topbar__title">{{nickName}}</text>
				</view>
				

				<template slot="append">
					<template v-if="conversationType=='GROUP'">
						<image class="member-icon"  src="../../static/icon/member.png" @tap="member"></image>
					</template>
					<template v-else>
						<view class="cl-topbar__icon" @tap="report">
							<!-- <cl-icon name="more"></cl-icon> -->
							举报
						</view>
					</template>
				</template>
			</cl-topbar>
		</view>
		
		<progress :percent="percent" show-info stroke-width="3" v-if="progressShow"/>

		<!-- 消息列表 -->
		<view class="message-list" @tap="onRetract">
			<scroll-view
				class="scroller"
				scroll-y
				scroll-with-animation
				:scroll-top="scroller.top"
				:upper-threshold="20"
				@scrolltoupper="refresh()"
			>
				<!-- 加载更多 -->
				<view class="loadmore" v-if="loading">
					<cl-loadmore  :finish="isCompleted" loading :divider="false"></cl-loadmore>
				</view>

				<!-- 内容块 -->
				<chat-message ref="message" :list="list" :conversationType="conversationType"></chat-message>
			</scroll-view>

			<!-- 录音弹窗 -->
			<cl-popup
				:visible.sync="voice.visible"
				direction="center"
				padding="0"
				border-radius="10rpx"
			>
				<view
					class="popup-voice"
					:class="[
						{
							'is-cancel': voiceIsCancel,
						},
					]"
				>
					<text class="popup-voice__time">{{ voice.duration | voice_duration }}</text>
					<text class="popup-voice__desc">松开发送，上滑取消</text>
				</view>
			</cl-popup>
		</view>
		
		<!-- 操作栏 -->
		<view class="opbar">
			<view class="main">
				<!-- 麦克风 -->
				<!-- #ifndef H5 -->
				<view class="icon">
					<text
						class="chat-iconfont icon-microphone"
						v-if="!op.isMicrophone"
						@tap="showMicrophone"
					></text>
					<text class="chat-iconfont icon-keyboard" @tap="hideMicrophone" v-else></text>
				</view>
				<!-- #endif -->

				<!-- 输入框 -->
				<view class="input">
					<button
						v-if="op.isMicrophone"
						class="press-btn"
						@longpress="onLongPress"
						@touchend="onRelease"
					>
						{{ voice.visible ? "松开结束" : "按住说话" }}
					</button>
						<cl-input
							v-else
							v-model="value"
							confirm-type="send"
							confirm-hold
							fill
							:placeholder="placeholder"
							:cursor-spacing="10"
							:adjust-position="false"
							@focus="onFocus"
							@blur="onBlur"
							@confirm="onTextSend"
							@keyboardheightchange="onKeyBoardHeightChange"
						></cl-input>
				</view>

				<!-- 表情图标 -->
				<view class="icon">
					<text 
						class="chat-iconfont icon-emoji"
						v-if="!op.isEmoji"
						@tap="showEmoji"
					></text>
					<text class="chat-iconfont icon-keyboard" v-else @tap="hideEmoji"></text>
				</view>
				
				<!-- 工具栏图标 -->
				<template v-if="value == ''">
					<view class="icon send">
						<text
							class="chat-iconfont icon-add-circle"
							v-if="!op.isTools"
							@tap="showTools"
						></text>
						<text class="chat-iconfont icon-subtract-circle" @tap="hideTools" v-else></text>
					</view>
				</template>
				<template v-else>
					<!-- 发送按钮 -->
					<view class="icon send">
						<text class="send-button" @tap="onTextSend">发送</text>
					</view>
				</template>
			</view>

			<view class="append">
				<!-- 工具栏 -->
				<chat-tools :visible="op.isTools" :userId="userID" :conversationType="conversationType"></chat-tools>
				
				<!-- 表情 -->
				<chat-emoji :visible="op.isEmoji" @select="onEmojiSelect"></chat-emoji>
			</view>
		</view>

		<!-- 视频弹窗 -->
		<cl-popup
			:visible.sync="video.visible"
			direction="center"
			force-update
			padding="0"
			border-radius="10rpx"
			@close="onVideoClose"
		>
			<video id="video" autoplay :src="video.url" style="display: block"></video>
		</cl-popup>
		
		<member ref="member"></member>
	</view>
</template>

<script>
import { debounce } from "cl-uni/utils";
import ChatTools from "./components/tools";
import ChatMessage from "./components/message";
import ChatEmoji from "./components/emoji";
import Member from "./components/member";

// 录音设备
const recorderManager = uni.getRecorderManager();

// 平台
const { platform } = uni.getSystemInfoSync();

export default {
	components: {
		ChatTools,
		ChatMessage,
		ChatEmoji,
		Member,
	},

	data() {
		return {
			userInfos: [],
			placeholder:"",
			conversationID:"",
			conversationType:"",
			percent:0,
			progressShow:false,
			firstLoad: true,
			isCompleted:false,
			nextReqMessageID:null,
			userID:0,
			nickName:"",
			// 平台
			platform,
			// 输入框文本
			value: "",
			// 键盘高度
			keyBoardHeight: 0,
			// 聊天记录数据
			// list: [
			// 	{
			// 		contentType: 0,
			// 		fromId: 1,
			// 		content: {
			// 			text: "Hello",
			// 		},
			// 	},
			// 	{
			// 		contentType: 2,
			// 		fromId: 2,
			// 		name: "神仙都没用",
			// 		avatarUrl:
			// 			"https://cool-comm.oss-cn-shenzhen.aliyuncs.com/show/imgs/chat/avatar/5.jpg",
			// 		content: {
			// 			imageUrl:
			// 				"https://cool-comm.oss-cn-shenzhen.aliyuncs.com/show/imgs/chat/face-with-party-horn-and-party-hat.png",
			// 		},
			// 	},
			// ],
			// 底部操作栏配置
			list: [],
			op: {
				isMicrophone: false,
				isEmoji: false,
				isTools: false,
			},
			// 滚动条配置
			scroller: {
				top: 0,
				intoView: "",
			},
			// 视频配置
			video: {
				visible: false,
			},
			// 音频配置
			voice: {
				visible: false,
				duration: 0,
				timer: null,
				down: 0,
				move: 0,
			},
			// 加载进度
			loading: false,
		};
	},
	onLoad(option) {
		this.userID = JSON.parse(decodeURIComponent(option.userID));
		this.nickName = JSON.parse(decodeURIComponent(option.nickName));
		this.conversationID = JSON.parse(decodeURIComponent(option.conversationID));
		this.conversationType = JSON.parse(decodeURIComponent(option.conversationType));
		if(this.conversationType == "GROUP"){
			this.placeholder = "发布违规言论会被禁言哦~";
		}
		
		this.TIM.setMessageRead(this.conversationID);
		
		this.setList();
		this.getUserInfo();
		uni.$on('messageUpdate',this.acceptMessage)
		uni.$on('messageProgress',this.messageProgress)
	},
	computed: {
		// 计算屏幕高度
		height() {
			return this.keyBoardHeight > 0
				? `calc(100% - ${this.keyBoardHeight}px + env(safe-area-inset-bottom))`
				: "100%";
		},

		// 录音滑动是否取消
		voiceIsCancel() {
			return this.voice.move ? this.voice.down - this.voice.move > 50 : false;
		},
	},

	filters: {
		voice_duration(t) {
			return `00:${t < 10 ? `0${t}` : t}`;
		},
	},
	methods: {
		async getUserInfo(){
			let [err,res] = await this.$http.get('Group/members',{'id': this.userID, 'type': this.conversationType});
			
			if(!this.$http.errorCheck(err,res)){
				return;
			}
			
			this.userInfos = res.data.data;
			this.setUserInfo();
		},
		setUserInfo(){
			if(this.list.length == 0 || this.userInfos.length == 0){
				return
			}
			
			for(let i = 0; i < this.list.length; i++){
				let fromID = this.list[i].from
				
				for( let j = 0; j < this.userInfos.length; j++){
					if(fromID == this.userInfos[j].id){
						this.list[i].avatar = this.userInfos[j].user_icon;
						this.list[i].sex = this.userInfos[j].sex;
						break;
					}
				}
			}
			
			this.list = this.list
		},
		toDetail(){
			if(this.conversationType == "C2C"){
				uni.navigateTo({
					url: "/pages/detail/index?uid=" + this.userID,
				});
			}
		},
		report(){
			setTimeout(()=>{
				uni.showToast({ title: '举报成功，我们会尽快进行处理!', icon:"none" });
			}, 500);
		},
		member(){
			this.$refs.member.open(this.userID);
		},
		refresh(){
			this.loading = true;
			
			if(this.isCompleted){
				return;
			}
			
			this.setList();
		},
		messageProgress(e){
			this.percent = e * 100;
			
			if(e == 1){
				this.progressShow = false;
			}else{
				this.progressShow = true;
			}
		},
		timestampToTime(timestamp){
			var date = new Date(timestamp * 1000);//时间戳为10位需*1000，时间戳为13位的话不需乘1000
			var Y = date.getFullYear() + '-';
			var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
			//var D = date.getDate() + ' ';
			var D = (date.getDate() + 1 < 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
			var h = date.getHours() + ':';
			var m = (date.getMinutes() + 1 < 10 ? '0' + (date.getMinutes()) : date.getMinutes()) + ' ';
			var s = date.getSeconds();
			return M + D + h + m;
		},
		acceptMessage(message){
			for(let i = 0; i < message.length; i++){
				if(message[i].conversationID == this.conversationID){
					this.list.push(message[i]);
					this.scrollToBottom();
				}
			}
		},
		async setList(){
			let res = await this.TIM.getMessageList(this.conversationID, this.nextReqMessageID);
			let messageList = res.data.messageList;
			this.isCompleted = res.data.isCompleted;
			this.nextReqMessageID = res.data.nextReqMessageID;
			
			for(let i = 0; i < messageList.length; i++){
				messageList[i].create_time = this.timestampToTime(messageList[i].time);
				messageList[i].sex = "3";
			}
			
			if(this.firstLoad){
				this.list = messageList;
				this.scrollToBottom();
			}else{
				this.list = messageList.concat(this.list);
			}
			
			this.firstLoad = false;
			uni.stopPullDownRefresh();
			
			this.loading = false;
			this.setUserInfo();
		},
		
		// 监听键盘高度
		onKeyBoardHeightChange(e) {
			this.keyBoardHeight = e.detail.height;
		},

		// 滑动监听
		onTouchMove(e) {
			if (this.voice.visible) {
				// 记录移动的位置
				this.voice.move = e.changedTouches[0].clientY;
			}
		},

		// 长按说话
		onLongPress(e) {
			uni.authorize({
				scope: 'scope.record',
				success() {
				    uni.getLocation()
				}
			});
			
			// 关闭已存在播放声音
			this.$refs["message"].voicePause();
			
			console.log("按下按钮了");
			
			this.$nextTick(() => {
				// 记录按下位置
				this.voice.down = e.touches[0].pageY;
				// 清空移动位置
				this.voice.move = 0;
				// 显示弹窗
				this.voice.visible = true;
				// 开始录音
				recorderManager.start({
					// duration: 60000,
					// sampleRate: 44100,
					// numberOfChannels: 1,
					// encodeBitRate: 192000,
					// format: "aac",
				});
				// 计数器
				this.voice.timer = setInterval(() => {
					if (this.voice.duration >= 60) {
						this.onRelease(e);
					} else {
						this.voice.duration += 1;
					}
				}, 1000);
			});
		},

		// 松开
		onRelease(e) {
			// 记录移动位置
			this.voice.move = e.changedTouches[0].clientY;
			let duration = this.voice.duration * 1000;
			
			console.log("松开按钮了");
			
			// 暂停事件
			recorderManager.onStop((res) => {
				// 判断是否取消
				if (!this.voiceIsCancel) {
					res.duration = duration;
					res.size = 34271;
					this.TIM.sendAudioMessage(res, this.userID, this.conversationType);
				}
			});
			// 清除计时器
			clearInterval(this.voice.timer);
			// 暂停录音
			recorderManager.stop();
			// 关闭弹窗
			this.voice.visible = false;
			// 清空时常
			this.voice.duration = 0;
		},

		// 显示麦克风
		showMicrophone() {
			this.op.isMicrophone = true;
			this.hideTools();
			this.hideEmoji();
			this.hideKeyBoard();
		},

		// 隐藏麦克风
		hideMicrophone() {
			this.op.isMicrophone = false;
		},

		// 显示表情
		showEmoji() {
			this.op.isEmoji = true;
			this.hideTools();
			this.hideMicrophone();
			this.scrollToBottom();
		},

		// 隐藏表情
		hideEmoji() {
			this.op.isEmoji = false;
		},

		// 显示工具栏
		showTools() {
			this.op.isTools = true;
			this.hideEmoji();
			this.hideMicrophone();
			this.scrollToBottom();
		},

		// 隐藏工具栏
		hideTools() {
			this.op.isTools = false;
		},

		// 隐藏键盘
		hideKeyBoard() {
			this.keyBoardHeight = 0;
		},

		// 滑动到底部
		scrollToBottom: debounce(function () {
			this.$nextTick(() => {
				this.scroller.top = 2000000 + parseInt(Math.random() * 100);
			});
		}, 100),

		// 收起
		onRetract() {
			this.hideTools();
			this.hideEmoji();
		},

		// 聚焦
		onFocus() {
			this.hideEmoji();
			this.hideTools();
			this.scrollToBottom();
		},

		// 失焦
		onBlur() {
			this.hideKeyBoard();
		},

		// 发送消息
		onTextSend() {
			if (this.value) {
				this.TIM.sendTextMessage(this.value, this.userID, this.conversationType);
				this.value = "";
			}
			
			if (this.userID == "51"){
				setTimeout(()=>{
					this.hackMessage()
				}, 1000);
			}
		},
		
		hackMessage(){
			if(this.list.length > 0){
				let item = JSON.parse(JSON.stringify(this.list[0]))
				item.avatar = "/static/logo.png";
				item._mode = "text";
				item.payload.text = "客服小姐姐正在赶来，请稍后~"
				item.from = "51"
				this.list.push(item)
			}else{
				this.list.push(
					{
						avatar: "/static/logo.png",
						_mode: "text",
						payload: {
							text: "客服小姐姐正在赶来，请稍后~"
						},
						from: "51"
					}
				)
			}
		},

		// 表情选择
		onEmojiSelect(e) {
			this.value = this.value + e;
		},


		// 追加数据到开头
		prepend(...data) {
			this.list.unshift(...data.filter(Boolean).reverse());
		},

		// 追加数据到结尾
		append(...data) {
			this.list.push(
				...data
					.map((e) => {
						e.animation = true;
						return e;
					})
					.filter(Boolean)
			);
			this.scrollToBottom();
		},

		// 关闭视频弹窗
		onVideoClose() {
			const video = uni.createVideoContext("video");
			video.pause();
		}
	},
};
</script>

<style lang="scss">
@import "./static/css/iconfont.scss";
page {
	height: 100%;
	overflow: hidden;
	background-color: #fff;
}
</style>

<style lang="scss" scoped>
.page-session {
	display: flex;
	flex-direction: column;
	padding-bottom: env(safe-area-inset-bottom);
	box-sizing: border-box;
	height: 100%;

	.message-list {
		flex: 1;
		overflow: hidden;
		background-color: #f7f7f7;
		position: relative;

		.loadmore {
			margin: 10rpx 0;
		}

		.scroller {
			height: 100%;
		}

		/deep/.cl-popup {
			&__wrapper {
				position: absolute;
			}
		}
	}

	.opbar {
		flex-shrink: 0;
		z-index: 9;
		background-color: #fff;
		border-top: 1rpx solid #f7f7f7;

		.main {
			display: flex;
			align-items: center;
			height: 100rpx;
			
			.send{
				margin-right: 30rpx;
			}

			.icon {
				height: 80rpx;
				width: 80rpx;
				line-height: 80rpx;
				text-align: center;
				flex-shrink: 0;

				.chat-iconfont {
					font-size: 60rpx;
				}
				
				.send-button{
					background-color: #66C67D;
					color: #F7FFFB;
					border-radius: 10rpx;
					padding: 5rpx 10rpx;
					font-size: 30rpx;
				}
			}

			.input {
				flex: 1;
				margin: 0 10rpx;
				height: 70rpx;
				line-height: 70rpx;

				.press-btn {
					display: inline-block;
					height: 70rpx;
					width: 100%;
					line-height: 70rpx;
					color: #666;
					border: 1rpx solid #dcdfe6;
					font-size: 24rpx;
					background-color: #fff;
					margin: 0;
					border-radius: 70rpx;
					box-sizing: border-box;

					&::after {
						border: 0;
					}

					&:active {
						background-color: #f7f7f7;
					}
				}
			}
		}
	}

	.popup-voice {
		display: flex;
		flex-direction: column;
		align-items: center;
		padding: 20rpx;

		&.is-cancel {
			background-color: red;
			color: #fff;
		}

		&__time {
			font-size: 28rpx;
			margin-bottom: 20rpx;
			letter-spacing: 1rpx;
		}

		&__desc {
			font-size: 24rpx;
		}
	}
}
.cl-topbar__icon{
	font-size: 25rpx;
	color: red;
	padding: 0rpx 10rpx;
}
.member-icon{
	width: 50rpx;
	height: 50rpx;
	margin-right: 30rpx;
}
</style>
